第2章 动态分析技术
pizza大佬和阿鹏大佬之前推荐了xdbg,我也觉得xdbg的界面看起来更舒服。但在这一章里面xdbg篇幅很少,主要篇幅为ollydbg和windbg,不过主要的功能应该调试器都有,因此决定照着ollydbg的功能去摸索xdbg对应的功能,windbg较为硬核,待接触到内核部分再去了解。
TraceMe.exe流程分析¶
进入到子程序后,若想回看刚才单步跟踪的代码,可以按“-”(减号)键;若想让光标回到当前EIP,可以双击EIP寄存器
Ctrl+F9:执行到返回指令处
Alt+F9:执行到用户代码
获取文本框中的字符,通常使用GetDlgItemText或者GetWindowText函数
GetDlgItemText函数执行后,会把取出的文本放到由lpString指定的位置,是第三个参数
TraceMe.exe破解脚本:
#部分输入和常量表进行运算,直接照着校验逻辑写破解脚本即可;后续可把用户名随机生成从而得到序列号集 const = [0x0C, 0x0A, 0x13, 0x09, 0x0C, 0x0B, 0x0A, 0x08] name = "obliviate" sum = 0 j = 0 for i in range(3,len(name)): sum += ord(name[i]) * const[j] j += 1 print(sum)
常用断点¶
INT3¶
最常用,把指令机器码改成0xCC;绕过检测可以把断点设在函数内
硬件断点¶
对着想要断下的地址右键-断点-硬件断点,即可断下,最多可设置4个
原理:和DRx调试寄存器(DR0~DR7)有关
DR0~DR3:调试地址寄存器,保存硬件断点监视的地址
DR4~DR5:保留
DR6:调试寄存器组状态寄存器,用于记录是在哪个硬件断点断下。如果是DR0,那么DR6的第0位(最低位)被置1;如果是DR1,那么DR6的第1位置1,以此类推。
DR7:调试寄存器组控制寄存器
L0和G0(各1位):控制DR0是全局断点还是局部断点,G0=1则为全局,L0=1则为局部,L0/G0~L3/G3同理
LEN0(2位):指定断点下断的长度,00为1字节,01为2字节,11为4字节,LEN1~LEN3同理
R/W0:指定断点触发条件,00为只执行,01为写入数据,10为I/O端口断点,11为读或写数据断点,R/W1~3同理
GD:保护DRx,如果GD位为1,对DRx的任何访问都会触发int 1
内存断点¶
同上,对着想要断下的地址右键-断点-内存断点,最多可设置1个
原理:对所设的地址赋予不可访问/不可写属性,这样当访问/写入时就会产生异常
硬件访问/写入断点是在触发硬件断点的下一条指令处断下,而内存断点是在触发断点的指令处断下
消息断点¶
在句柄选项中的窗口列表,根据文本信息(比如一个按钮会有按钮上的字)找到相应的句柄,右击-消息断点,然后选择断在哪种消息。比如要在鼠标左键点击断下,就选择WM_LBUTTONUP
条件断点¶
对着要断的地址,右键-条件断点,之后设置条件
条件消息断点¶
在条件断点的基础上,可以选择输出日志,格式参考:http://help.x64dbg.com/en/latest/introduction/Formatting.html
比如输出寄存器eax的值,使用{eax};
输出某个地址的值,使用{mem;size@addr},其中size为字节数,addr为地址,但这个需要注意输出日志似乎是大端序